package com.boby.homecamera.helper

import android.Manifest
import android.content.pm.PackageManager
import android.media.AudioFormat
import android.media.AudioRecord
import android.media.MediaCodec
import android.media.MediaCodecInfo
import android.media.MediaFormat
import android.media.MediaRecorder
import androidx.annotation.RequiresPermission
import com.boby.homecamera.config.AppConfig
import com.pedro.library.util.AacMuxerRecordController

class AudioSender(private val byteArrayCallBack: (ByteArray) -> Unit) {

    private var audioRecord: AudioRecord? = null
    private var codec: MediaCodec? = null
    private var running = false
    private var sendThread:Thread? = null

    @RequiresPermission(Manifest.permission.RECORD_AUDIO)
    fun start() {
        val sampleRate = 16000
        val minBuf = AudioRecord.getMinBufferSize(
            sampleRate,
            AudioFormat.CHANNEL_IN_MONO,
            AudioFormat.ENCODING_PCM_16BIT
        )
        audioRecord = AudioRecord(
            MediaRecorder.AudioSource.VOICE_COMMUNICATION,
            sampleRate,
            AudioFormat.CHANNEL_IN_MONO,
            AudioFormat.ENCODING_PCM_16BIT,
            minBuf
        )

        codec = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_AUDIO_AAC).apply {
            val format = MediaFormat.createAudioFormat(
                MediaFormat.MIMETYPE_AUDIO_AAC, sampleRate, 1
            )
            format.setInteger(MediaFormat.KEY_BIT_RATE, AppConfig.Record.RECORD_AUDIO_BITRATE)
            format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC)
            configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE)
            start()
        }

        running = true
        audioRecord?.startRecording()

        sendThread = Thread {
            val buffer = ByteArray(minBuf)
            val codec = codec!!
            val info = MediaCodec.BufferInfo()

            while (running) {
                val len = audioRecord!!.read(buffer, 0, buffer.size)
                if (len > 0) {
                    val inputIndex = codec.dequeueInputBuffer(10000)
                    if (inputIndex >= 0) {
                        val inputBuffer = codec.getInputBuffer(inputIndex)!!
                        inputBuffer.clear()
                        inputBuffer.put(buffer, 0, len)
                        codec.queueInputBuffer(inputIndex, 0, len, System.nanoTime() / 1000, 0)
                    }

                    var outputIndex = codec.dequeueOutputBuffer(info, 10000)
                    while (outputIndex >= 0) {
                        val outBuffer = codec.getOutputBuffer(outputIndex)!!
                        val outData = ByteArray(info.size)
                        outBuffer.get(outData)
                        outBuffer.clear()

                        // WebSocket 发送音频帧
//                        byteArrayCallBack.invoke(addAdtsHeader(outData))
                        byteArrayCallBack.invoke(outData)
                        codec.releaseOutputBuffer(outputIndex, false)
                        outputIndex = codec.dequeueOutputBuffer(info, 0)
                    }
                }
            }

            codec.stop()
            codec.release()
            audioRecord?.stop()
            audioRecord?.release()
        }
        sendThread?.start()
    }

    fun stop() {
        running = false

        try {
            sendThread?.interrupt()
        }catch (e:Exception){
            e.printStackTrace()
        }

    }
    fun addAdtsHeader(aacData: ByteArray, sampleRate: Int = 16000): ByteArray {
        val freqIdx = when (sampleRate) {
            96000 -> 0
            88200 -> 1
            64000 -> 2
            48000 -> 3
            44100 -> 4
            32000 -> 5
            24000 -> 6
            22050 -> 7
            16000 -> 8
            12000 -> 9
            11025 -> 10
            8000 -> 11
            else -> 8
        }
        val chanCfg = 1
        val profile = 2 // AAC LC

        val adtsHeader = ByteArray(7)
        val packetLen = aacData.size + 7

        adtsHeader[0] = 0xFF.toByte()
        adtsHeader[1] = 0xF9.toByte()
        adtsHeader[2] = (((profile - 1) shl 6) + (freqIdx shl 2) + (chanCfg shr 2)).toByte()
        adtsHeader[3] = (((chanCfg and 3) shl 6) + (packetLen shr 11)).toByte()
        adtsHeader[4] = ((packetLen and 0x7FF) shr 3).toByte()
        adtsHeader[5] = (((packetLen and 7) shl 5) + 0x1F).toByte()
        adtsHeader[6] = 0xFC.toByte()

//        val adtsHeader = AacMuxerRecordController.createAdtsHeader(aacData.size, sampleRate, 1)
        return adtsHeader + aacData
    }

}
